Allow pciback to be placed into a permissive mode of operation whereby it allows
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 8 Mar 2006 16:32:36 +0000 (17:32 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Wed, 8 Mar 2006 16:32:36 +0000 (17:32 +0100)
PCI config writes to succeed by default. Currently this is the only way to allow
control of a device that has device-specific registers in the config space from
a driver domain.

echo Y >/sys/module/pciback/parameters/permissive

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/pciback/conf_space.c

index f08eafab3a21e7ac45dd954666501f96404930d5..9d1fe1ecaa727c3b087e019c9ab349e84a1035fc 100644 (file)
@@ -14,6 +14,9 @@
 #include "pciback.h"
 #include "conf_space.h"
 
+static int permissive = 0;
+module_param(permissive, bool, 0644);
+
 #define DEFINE_PCI_CONFIG(op,size,type)                                        \
 int pciback_##op##_config_##size                                                       \
 (struct pci_dev *dev, int offset, type value, void *data)      \
@@ -198,7 +201,7 @@ int pciback_config_read(struct pci_dev *dev, int offset, int size,
 
 int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value)
 {
-       int err = 0;
+       int err = 0, handled = 0;
        struct pciback_dev_data *dev_data = pci_get_drvdata(dev);
        struct config_field_entry *cfg_entry;
        struct config_field *field;
@@ -233,6 +236,21 @@ int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value)
                                              field_start - req_start);
 
                        err = conf_space_write(dev, cfg_entry, offset, tmp_val);
+                       handled = 1;
+               }
+       }
+
+       if (!handled && !err && permissive) {
+               switch (size) {
+               case 1:
+                       err = pci_write_config_byte(dev, offset, (u8)value);
+                       break;
+               case 2:
+                       err = pci_write_config_word(dev, offset, (u16)value);
+                       break;
+               case 4:
+                       err = pci_write_config_dword(dev, offset, (u32)value);
+                       break;
                }
        }